﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using App.Core.Extensions;
using App.Domain;
using App.Web.ViewModels;
using App.Web.Utility;
using AutoMapper;
using System.Data;
using App.Web.ViewModels.UtilityModels;

namespace App.Web.Areas.Private.Controllers
{
    [Authorize(Roles = "Company Admin,Company User")]
    public class InventoryController : BaseController
    {
		private AppEntities _Context = new AppEntities();
        
		#region Constructors
		public InventoryController()
		{
		}

		public InventoryController(UserViewModel currentUser)
			: base(currentUser)
        {
        }
		#endregion Constructors

		#region Action Methods
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Receive(String id)
        {
            Transaction transaction = null;
            int transactionID = id.ToInt();
            if (transactionID > 0)
                transaction = _Context.Transactions.Include("TransactionDetails").FirstOrDefault(P => P.ID == transactionID);
            else
            {
                transaction = new Transaction();
                transaction.IsReceive = true;
            }
            TransactionViewModel model = Mapper.Map<TransactionViewModel>(transaction);

            //ViewBag.IsReceive = transaction.IsReceive ? true : false;
            //ViewBag.IsPosted = transaction.IsPosted;
            return View(model);
        }


        public ActionResult Issue(String id)
        {
            Transaction transaction = null;
            int transactionID = id.ToInt();
            if (transactionID > 0)
                transaction = _Context.Transactions.Include("TransactionDetails").FirstOrDefault(P => P.ID == transactionID);
            else
            {
                transaction = new Transaction();
                transaction.IsIssue = true;
            }
            TransactionViewModel model = Mapper.Map<TransactionViewModel>(transaction);
            
            //ViewData[AppConstants.ViewDataKeys.SUB_MODEL] = true;
            //ViewBag.IsPosted = transaction.IsPosted;
            return View("Receive", model);
        }

//        public ActionResult List(String reqFrom)
//        {
//            UtilityDAO dao = new UtilityDAO();
//            App.Domain.DbParameter[] parameters = new[]{
//                new App.Domain.DbParameter("@CompanyID", LoggedInUser.Company.ID)
//                //,new App.Domain.DbParameter("@ID", LoggedInUser.Company.ID)
//            };
//            DataSet ds = dao.GetDataSet((reqFrom == "Receive") ? DbObject.SP.GET_RECEIVE_DETAILS : DbObject.SP.GET_ISSUE_DETAILS, parameters, true);
//            //DataTable dt = BuildDataTable();
//            //DateTime start = DateTime.Now;

//            string url = (reqFrom == "Receive") ? "/Private/Inventory/Receive/{0}" : "/Private/Inventory/Issue/{0}";
            
//            ListConfig config = App.Web.ViewModels.UtilityModels.ListConfigBuilder.Build(
//                @"Basic Information{ ReceivedDate | Store }, 
//                Details Information{ ReferenceNo | Description}",
//                ds.Tables[0], true, url);

//            //Picture{Image:<img src='/ProductImages/{0}' alt='{1}' title='{2}' />(ThumbImage ~ ID ~ Name)},
//            //Description{Description}

//            //ViewBag.ReqFrom = reqFrom;
//            if (reqFrom == "Issue")
//            {
//                ViewData[AppConstants.ViewDataKeys.SUB_MODEL] = true; 
//            }

//            ViewData[AppConstants.ViewDataKeys.LIST_CONFIG] = config;
//            return View();
//        }

        public ActionResult List(String type, String posted)
        {            
            ViewBag.RequestType = type.IsNullOrEmpty() ? "Receive" : type;
            ViewBag.IsPosted = posted.ToBoolean() ? "Yes" : "No";

            return View();
        }

        public PartialViewResult GetTransactionList(String type, String posted, String page, String id)
        {
            bool hasPosted = posted.ToBoolean();

            PagerConfig pagerConfig = new PagerConfig(id.ToInt() > 0 ? id.ToInt() : 1, ConfigReader.pageSize, 0);
            UtilityDAO dao = new UtilityDAO();
            DbParameter[] parameters = new[] {            
                new DbParameter("@CompanyID",  LoggedInUser.Company.ID),
                new DbParameter("@Type",  type),
                new DbParameter("@IsPosted",  hasPosted),
            };

            int totalRecord = 0;
            System.Data.DataSet ds =
                dao.GetPagedData(DbObject.SP.GET_INVENTORY_LIST,
                parameters, pagerConfig.PageNo, 2, out totalRecord, true);
            pagerConfig.TotalRecord = totalRecord;
            //ViewBag.SearchType = "WishList";
            ListConfig Config = new ListConfig(ds.Tables[0], pagerConfig);


            ViewData[AppConstants.ViewDataKeys.SUB_MODEL] = type;
            ViewBag.IsPosted = posted;
            return PartialView("_TransactionList", Config);
        }


        [HttpPost]
        public String Receive(String json, String isPost = "")//(TransactionViewModel viewModel)
        {
            System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            TransactionViewModel viewModel = serializer.Deserialize<TransactionViewModel>(json);
            UpdateInventory(viewModel, false);            
            return viewModel.ToJSON();
        }

        [HttpPost]
        public String Issue(String json, String isPost = "")//(TransactionViewModel viewModel)
        {
            System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            TransactionViewModel viewModel = serializer.Deserialize<TransactionViewModel>(json);
            UpdateInventory(viewModel, true);
            return viewModel.ToJSON();
        }

        private void UpdateInventory(TransactionViewModel viewModel, bool isIssue)
        {
            Transaction transaction = null;
            if (viewModel.ID == 0)
            {
                transaction = new Transaction();
                transaction.Code = GenerateReceiveCode();
                transaction.CreatedOn = DateTime.Now;
                transaction.CreatebBy = LoggedInUser.ID;
                _Context.Transactions.AddObject(transaction);
            }
            else
                transaction = _Context.Transactions.FirstOrDefault(P => P.ID == viewModel.ID);
            //transaction.Code = viewModel.Code;
            transaction.TransactionDate = viewModel.TransactionDate.ToDateTime();
            transaction.Description = viewModel.Description;
            transaction.StoreID = viewModel.StoreID;
            transaction.ReferenceNo = viewModel.ReferenceNo;
            transaction.ModifiedBy = LoggedInUser.ID;
            transaction.ModifiedOn = DateTime.Now;
            //This is a Receive Operation
            if (isIssue)
                transaction.IsIssue = true;
            else
                transaction.IsReceive = true;
            foreach (TransactionDetailViewModel detailViewModel in viewModel.TransactionDetails)
            {
                TransactionDetail detail = null;
                if (detailViewModel.ID == 0)
                {
                    detail = new TransactionDetail();
                    transaction.TransactionDetails.Add(detail);
                    detail.CreatebBy = LoggedInUser.ID;
                    detail.CreatedOn = DateTime.Now;
                }
                else
                    detail = transaction.TransactionDetails.FirstOrDefault(P => P.ID == detailViewModel.ID);
                detail.ProductID = detailViewModel.ProductID;
                detail.UnitPrice = detailViewModel.UnitPrice.ToDouble();
                detail.Description = detailViewModel.Description;
                detail.ReceiveQuantity = detailViewModel.ReceiveQuantity.ToInt();
                detail.ItemQuality = detailViewModel.ItemQuality;
                //detail.PhysicalStockQuantity = 
                //detail.CurrentStockQuantity = 
                detail.ModifiedBy = LoggedInUser.ID;
                detail.ModifiedOn = DateTime.Now;
            }
            _Context.SaveChanges();
            viewModel = Mapper.Map<TransactionViewModel>(transaction);
        }
        public String GenerateReceiveCode()
        {
            return String.Format("REC-{0}{1}{2}{3}{4}{5}", DateTime.Now.Day, DateTime.Now.Month, DateTime.Now.Year, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
        }
        //public ActionResult Issue(String id)
        //{
        //    return View();
        //}
        /// <summary>
        /// Deletes a transaction detail from database.
        /// </summary>
        /// <param name="detailId"></param>
        /// <returns>Returns a Status integer. Which means as follows
        /// -1 Denotes Invalid Request. Possible Hacking attempt
        /// -2 Denotes the Transaction has already been posted and cannot be deleted.
        /// +1 Denotes Delete operation was successfully.
        /// </returns>
        [HttpPost]
        public int Delete(String detailId)
        {
            int transactionDetailID = detailId.ToInt();
            if (transactionDetailID == 0)
                return -1;
            TransactionDetail detail = _Context.TransactionDetails.FirstOrDefault(P => P.ID == transactionDetailID);
            if (detail == null || detail.Transaction.Store.CompanyID != LoggedInUser.Company.ID)
                return -1;

            if (detail.HasPosted)
                return -2;

            _Context.TransactionDetails.DeleteObject(detail);
            _Context.SaveChanges();
            return 1;
        }
		#endregion Action Methods
		
		#region Helper Methods

        #endregion			
    }
}
